package com.jar.exercise.设计模式.单例.双重检查;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * @author 松鼠
 * @className Singleton
 * @description TODO
 * @date 2019-11-08 13:51
 */
public class Singleton {
	private Singleton() {
		System.out.println(Thread.currentThread().getName() + "\t" + "SingletonDemo构造方法创建");
    }

    /**
     * <p>volatile 是为了防止指令重排造成的多线程问题，
     * <p>new Singleton()经过了三个步骤
     * <p>1、分配内存
     * <p>2、创建对象，初始化
     * <p>3、对象地址引用
     * <p>假如这个步骤发生了变化 132，那么另一个线程过来就会发现instance！=null，但是还没有初始化
     */
    private volatile static Singleton instance;

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }


	public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

//        for (int i = 0; i < 10; i++) {
//            new Thread(Singleton::getInstance, String.valueOf(i)).start();
//        }
		Singleton instance = Singleton.getInstance();
		Singleton instance1 = Singleton.getInstance();
		System.out.println(instance);
		Class<? extends Singleton> aClass = Singleton.getInstance().getClass();
		Constructor<? extends Singleton> declaredConstructor = aClass.getDeclaredConstructor();
		Singleton singleton = declaredConstructor.newInstance();
		declaredConstructor.setAccessible(true);
		System.out.println(singleton);
		System.out.println(instance1);

	}
}
